﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Threading;

namespace FandangoStormer
{
    class FandangoClient
    {
        public delegate void LoginPerformedHandler(FandangoClient client, bool successful);
        public event LoginPerformedHandler LoginPerformed;

        public delegate void VotePerformedHandler(FandangoClient client, bool successful);
        public event VotePerformedHandler VotePerformed;

        public delegate void AlreadVotedHandler(FandangoClient client);
        public event AlreadVotedHandler AlreadVoted;

        public Communications communications = new Communications();
        BackgroundWorker worker = new BackgroundWorker();
        public VoteInformation voteInformation;

        public FandangoClient()
        {
            worker.DoWork += worker_DoWork;
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (voteInformation.Username == null || Login())
                Vote();
        }

        public class VoteInformation
        {
            public string ReviewURL { get; set; }
            public string Poster { get; set; }
            public string Username { get; set; }
            public string Password { get; set; }
            public bool DownVote { get; set; }
            public Communications.ProxyInfo Proxy { get; set; }
        }

        public void PerformVote(VoteInformation voteInformation, bool block = false)
        {
            this.voteInformation = voteInformation;
            communications.proxyInfo = voteInformation.Proxy;
            worker.RunWorkerAsync();
            if (block) while (worker.IsBusy) Thread.Sleep(200);
        }

        bool Login()
        {
            bool successful = false;
            try
            {
                string loginUrl = "https://www.fandango.com/Logon.aspx?source=signout";
                string loginWebPage = communications.PerformGet(loginUrl);
                string viewstate = Regex.Match(loginWebPage, "id=\"__VIEWSTATE\" value=\"([^\"]*)\" />").Groups[1].Value;

                communications.ClearCookies();

                var postData = new Communications.PostData();
                postData.AddValue("__EVENTTARGET", "");
                postData.AddValue("__EVENTARGUMENT", "");
                postData.AddValue("__VIEWSTATE", viewstate);
                postData.AddValue("HeaderStandard$searchControl$LocationSearchTextBox", "Enter ZIP or City, State");
                postData.AddValue("HeaderStandard$searchControl$ctl00$SearchTextBox", "Movies + Actors");
                postData.AddValue("UsernameBox", voteInformation.Username);
                postData.AddValue("PasswordBox", voteInformation.Password);
                postData.AddValue("SignInButton.x", new Random(DateTime.Now.Second).Next(1, 70).ToString());
                postData.AddValue("SignInButton.y", new Random(DateTime.Now.Second).Next(1, 15).ToString());
                postData.AddValue("newsletterFooter", "Enter E-mail Address");
                postData.AddValue("footerControl$ctl00$SearchTextBox", "Movies + Actors");
                var result = communications.PerformPost("https://www.fandango.com/Logon.aspx?source=signout", postData, referer: loginUrl, allowAutoRedirect: true);

                successful = result.Contains("Member Since");
            }
            catch { }

            LoginPerformed(this, successful);
            return successful;
        }

        bool Vote()
        {
            bool successful = false;
            try
            {

                //string movieID = voteInformation.ReviewURL.Contains("mid") ? Regex.Match(voteInformation.ReviewURL, "&mid=([^\"]*)&pn").Groups[1].Value : Regex.Match(voteInformation.ReviewURL, ".com/([^\"]*)/").Groups[1].Value.Split('_')[1];
                string movieID = voteInformation.ReviewURL.Contains('_') ? voteInformation.ReviewURL.Split('_')[1] : voteInformation.ReviewURL;
                string voteUrl = string.Format("http://www.fandango.com/frdi/ajax/Ajax.aspx?hlpvt={0}&favid={1}&cuname={2}&favtype=Movie&aop=HelpfulnessUpdate&r={3}", new object[] { voteInformation.DownVote ? "false" : "true", movieID, voteInformation.Poster, new Random(DateTime.Now.Millisecond).Next(2000, 80000).ToString() });
                var result = communications.PerformGet(voteUrl, referer: voteInformation.ReviewURL);
                successful = true;
            }
            catch { }

            VotePerformed(this, successful);
            return successful;
        }
    }
}
